package com.wuage.interfaces.account;

import com.wuage.application.IEmailService;
import com.wuage.application.IUacAccountService;
import com.wuage.domain.model.UacAccount;
import com.wuage.infrastructure.exception.BizException;
import com.wuage.infrastructure.status.BizResultCode;
import com.wuage.infrastructure.utils.*;
import com.wuage.interfaces.BaseController;
import com.wuage.interfaces.account.domain.AccountForgetPasswordDO;
import com.wuage.interfaces.account.domain.AccountPasswordResetDO;
import com.wuage.interfaces.account.domain.AccountRegisterDO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;

/**
 * @author Shynin
 * @version 1.0
 * @date 2020-09-04 14:53
 */
@Slf4j
@RestController
@RequestMapping("/account")
@Api(tags = "{用户}-相关接口")
public class AccountController extends BaseController {

    @Resource
    private IUacAccountService accountService;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private IEmailService emailService;

    @GetMapping("/authCode")
    @ApiOperation("获取手机验证码")
    public Response<String> authCode(@ApiParam(value = "手机号", required = true) @RequestParam("telephone") String telephone) {
        if(!PhoneFormatCheckUtils.isPhoneLegal(telephone)) {
            throw new BizException(BizResultCode.VERIFICATION_ERROR);
        }
        log.info("生成验证码");
        String authCode = GeneratorUtils.generateNumberString(4);
        // todo 发送短信验证码到手机
        log.info("验证码为: {}", authCode);
        redisUtils.set(telephone, authCode, 200);
        log.info("验证码已存到redis中");
        return Response.success(authCode);
    }

    @GetMapping("/authCode/check")
    @ApiOperation("验证手机验证码是否正确")
    public Response<Boolean> checkAuthCode(@ApiParam(value = "手机号", required = true) @RequestParam("telephone") String telephone,
                                           @ApiParam(value = "验证码", required = true) @RequestParam("authCode") String authCode) {
        String authCodeInSys = (String) redisUtils.get(telephone);
        if(StringUtils.isEmpty(authCodeInSys) || !authCodeInSys.equals(authCode)) {
            throw new BizException(BizResultCode.AUTH_CODE_ERROR);
        }
        return Response.success(true);
    }

    @ApiOperation("注册用户")
    @PostMapping()
    public Response<Boolean> register(@RequestBody @Valid AccountRegisterDO accountRegisterDO) {
        if(!accountRegisterDO.getPassword().equals(accountRegisterDO.getConfirmPassword())) {
            throw new BizException(BizResultCode.PASSWORD_IS_NOT_SAME);
        }
        String authCode = (String) redisUtils.get(accountRegisterDO.getUsername());
        if(StringUtils.isEmpty(authCode) || !authCode.equals(accountRegisterDO.getAuthCode())) {
            throw new BizException(BizResultCode.AUTH_CODE_ERROR);
        }
        Boolean register = accountService.register(accountRegisterDO);
        return Response.success(register);
    }


    @ApiOperation("发送邮箱绑定邮件")
    @PostMapping("/email")
    public Response<Boolean> sendBindEmail(@ApiParam(value = "邮箱", required = true) @RequestParam("email") String email) {
        Boolean result = emailService.sendAuthEmail(email);
        return Response.success(result);
    }

    @ApiOperation("邮箱绑定(前端不需要调用，由邮箱跳转调用)")
    @GetMapping("/email/authentication/{userId}/{email}")
    public Response<Boolean> bindEmail(@PathVariable(value = "userId", required = true) Long userId,
                                       @PathVariable(value = "email", required = true) String email) {
        Long userIdSys = (Long) redisUtils.get(email);
        if(!userIdSys.equals(userId)) {
            throw new BizException(BizResultCode.AUTH_CODE_ERROR);
        }
        Boolean result = accountService.bindEmail(userId, email);
        return Response.success(result);
    }

    @ApiOperation("修改密码")
    @PutMapping("/password")
    public Response<Boolean> resetPassword(@Valid @RequestBody AccountPasswordResetDO accountPasswordResetDO) {
        if(!accountPasswordResetDO.getPassword().equals(accountPasswordResetDO.getConfirmPassword())) {
            throw BizResultCode.PASSWORD_IS_NOT_SAME.toException();
        }
        Long userId = JwtUtils.getLoginUser().getId();
        UacAccount uacAccount = accountService.getById(userId);
        String authCode = (String) redisUtils.get(uacAccount.getUsername());
        if(StringUtils.isEmpty(authCode) || !authCode.equals(accountPasswordResetDO.getAuthCode())) {
            throw BizResultCode.AUTH_CODE_ERROR.toException();
        }
        Boolean result = accountService.resetPassword(userId, accountPasswordResetDO.getPassword());
        return Response.success(result);
    }

    @ApiOperation("忘记密码")
    @PutMapping("/forget/password")
    public Response<Boolean> forgetPassword(@Valid @RequestBody AccountForgetPasswordDO accountForgetPasswordDO) {
        if(!accountForgetPasswordDO.getPassword().equals(accountForgetPasswordDO.getConfirmPassword())) {
            throw BizResultCode.PASSWORD_IS_NOT_SAME.toException();
        }
        UacAccount userByUsername = accountService.getUserByUsername(accountForgetPasswordDO.getUsername());
        if(Objects.isNull(userByUsername)) {
            throw BizResultCode.USER_NOT_EXISTS.toException();
        }
        String authCode = (String) redisUtils.get(userByUsername.getUsername());
        if(StringUtils.isEmpty(authCode) || !authCode.equals(accountForgetPasswordDO.getAuthCode())) {
            throw BizResultCode.AUTH_CODE_ERROR.toException();
        }

        Boolean result = accountService.resetPassword(userByUsername.getId(), accountForgetPasswordDO.getPassword());
        return Response.success(result);
    }

}
